package ch.zhaw.cctd.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.zhaw.cctd.domain.DomainFacade;
import ch.zhaw.cctd.domain.prototype.TowerPrototype;
import ch.zhaw.cctd.logic.network.NetworkException;

/**
 * Ist verantwortlich für die Darstellung des effektive Spieles. Greift auf alle
 * Spielobjekte zu, um diese darzustellen. Ermöglicht das versenden von
 * Ressourcen und das platzieren von Towers.
 * 
 * @author Lukas Spirig
 * 
 */
public class MatchGUI implements ActionListener, KeyEventDispatcher {

	private static final Logger logger = LoggerFactory.getLogger(MatchGUI.class);

	private CCTDFrame frame;
	private ChatGUI chat;

	private JLabel cntCreeps = new JLabel("0");
	private JLabel cntWaves = new JLabel("0");
	private JLabel cntGold = new JLabel("0");
	private JLabel time = new JLabel("00:00");
	private JPanel fTowers = new JPanel();
	private JPanel defTowers;
	private JScrollPane gamePane;
	private FieldGUI field;
	private HashMap<JButton, TowerPrototype> towerButtons = new HashMap<JButton, TowerPrototype>();
	private JButton sendGold = new JButton("Schicken");

	public MatchGUI(CCTDFrame frame) {
		this.frame = frame;
		KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
	}

	public void start() {
		Container c = frame.getContentPane();
		c.removeAll();
		c.setLayout(new BorderLayout());

		JPanel header = new JPanel(new GridLayout(1, 4));
		header.setBackground(Color.DARK_GRAY);

		JPanel h1 = new JPanel(new GridBagLayout());
		h1.add(new JLabel("Zeit: "));
		h1.add(time);
		header.add(h1);

		JPanel h2 = new JPanel(new GridBagLayout());
		h2.add(new JLabel("Welle: "));
		h2.add(cntWaves);
		header.add(h2);

		JPanel h3 = new JPanel(new GridBagLayout());
		h3.add(new JLabel("Creeps: "));
		h3.add(cntCreeps);
		header.add(h3);

		JPanel h4 = new JPanel(new GridBagLayout());
		h4.add(new JLabel("Gold: "));
		h4.add(cntGold);
		h4.add(new JLabel("  "));
		sendGold.addActionListener(this);
		h4.add(sendGold);
		header.add(h4);

		c.add(header, BorderLayout.PAGE_START);

		JPanel footer = new JPanel(new BorderLayout());

		List<TowerPrototype> towers = DomainFacade.getPrototypeList().getPrototypes(TowerPrototype.class);
		int cntTowers = towers.size();
		int rows = 3;
		int cols = (int) Math.ceil((double) cntTowers / rows);

		for (int i = 0; i < cntTowers; i++) {
			TowerPrototype tp = towers.get(i);
			JButton btn = new JButton(tp.getTitle());
			btn.addActionListener(this);
			towerButtons.put(btn, tp);
		}

		defTowers = new JPanel(new GridLayout(rows, cols));
		Set<JButton> tb = towerButtons.keySet();
		Iterator<JButton> tbit = tb.iterator();

		while (tbit.hasNext()) {
			defTowers.add(tbit.next());
		}

		fTowers.add(defTowers);
		footer.add(fTowers, BorderLayout.LINE_END);

		chat = new ChatGUI();

		try {
			DomainFacade.registerChatEventListener(chat);
		} catch (NetworkException e) {
			if (e.isFatalError()) {
				// TODO close connection to server and stop game...
			}
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		footer.add(chat, BorderLayout.CENTER);

		gamePane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		gamePane.setSize(200, 200);
		gamePane.setPreferredSize(new Dimension(300, 300));

		field = new FieldGUI(this);
		field.runGame();
		gamePane.setViewportView(field);

		// GamePane
		c.add(gamePane, BorderLayout.CENTER);
		// Chat
		c.add(footer, BorderLayout.PAGE_END);
		frame.setContentPane(c);

	}
	
	public JViewport getViewport() {
		return this.gamePane.getViewport();
	}
	
	public ChatGUI getChat() {
		return chat;
	}

	public void setCntCreeps(String cntCreeps) {
		this.cntCreeps.setText(cntCreeps);
	}

	public void setCntWaves(String cntWaves) {
		this.cntWaves.setText(cntWaves);
	}

	public void setCntGold(String cntGold) {
		this.cntGold.setText(cntGold);
	}

	public void setTime(String time) {
		this.time.setText(time);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(sendGold)) {
			logger.trace("Send gold");
		} else if (towerButtons.containsKey(e.getSource())) {
			TowerPrototype tower = towerButtons.get(e.getSource());

			if (DomainFacade.getLocalPlayerMoney() >= tower.getCost()) {
				field.placeTower(tower);
			} else {

			}

			logger.trace("tower build");
		}
	}

	public void stopThreads() {

		if (field != null)
			field.stopThreads();

	}

	@Override
	public boolean dispatchKeyEvent(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
			logger.trace("Menu Window opened");
			frame.getMenuGUI().display();
		}
		return false;
	}
	
	public void error(String title, String string) {
		frame.error(title, string);
	}
	
	public void message(String title, String string) {
		frame.message(title, string);
	}
}
